package com.itdct.onflow.core.util

import org.redisson.api.RLock
import org.redisson.api.RedissonClient
import org.springframework.stereotype.Component
import java.util.concurrent.TimeUnit

/**
 * @author Zhouwx
 * @date 2025/9/28 10:08:06
 * @version 1.0
 * @description
 */
@Component
class RedisReentrantLock(
    val redissonClient: RedissonClient
) {

    /**
     * 获取可重入锁对象。
     * @param lockKey 锁的键名
     * @return RLock 对象，它已经具备了可重入、看门狗自动续期等所有特性。
     */
    fun getLock(lockKey: String): RLock {
        return redissonClient.getLock(lockKey)
    }

    /**
     * 尝试获取锁
     */
    fun tryLock(lockKey: String, waitTime: Long, leaseTime: Long): Boolean {
        val rLock = getLock(lockKey)
        return try {
            rLock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS)
        } catch (e: InterruptedException) {
            Thread.currentThread().interrupt()
            false
        }
    }

    /**
     * 阻塞直到获取锁（常用简便方法，默认使用看门狗机制自动续期）
     */
    fun lock(lockKey: String) {
        val lock = getLock(lockKey)
        lock.lock()
    }

    /**
     * 释放锁。安全释放，会检查是否由当前线程持有。
     */
    fun unlock(lockKey: String) {
        val lock = getLock(lockKey)
        // 判断锁是否存在且由当前线程持有，避免误释放其他线程的锁
        if (lock.isHeldByCurrentThread) {
            lock.unlock()
        }
    }

    /**
     * 强制释放锁（有风险，慎用）
     */
    fun forceUnlock(lockKey: String) {
        val lock = getLock(lockKey)
        lock.forceUnlock()
    }

}